#include "mat_scoring.h"
#include "mat_ui_achievement_gain.h"
#include "mat_gamerule.h"
#include "mat_level_manager.h"
#include "mat_sfx_manager.h"
#include "mat_game.h"
#include "mat_char_animation.h"
#include "gen_game_state.h"

#include "ui/ui_progress.h"
#include "ui/ui_manager.h"
#include "application/game_application.h"
#include "application/game_rms.h"
#include "graphics/graphics_util.h"
#include "ui/ui_manager.h"
#include "ui/ui_flexeffect.h"
#include "nextpeer/np_manager.h"


#include <algorithm>



MATScoring::MATScoring() :	m_MatchCount(0),						
							m_NextPeerScoreReportDelay(4.0f)
{

	ui::UIWidget *pScorePos = ui::UIManager::Instance().GetWidget("pos_score");
	if(pScorePos)
		pScorePos->SetTextA("");

	m_pUIProgressScore = (ui::UIProgress*)ui::UIManager::Instance().GetWidget("progress_score");	

	m_Score.Load("ui_img/time_number.lua",pScorePos);

	char Buffer[256];		
	for(int i = 0; i < 3; i++)
	{
		sprintf(Buffer, "star%i", i+1);
		m_pUIStars[i] = ui::UIManager::Instance().GetWidget(Buffer);
		
	}
	
}

MATScoring&	MATScoring::Instance()
{
	static MATScoring inst;
	return inst;
}


void		MATScoring::AddMatched(const std::vector<MATGem*>& List,
										const std::vector<int>&	XList,
										const std::vector<int>&	YList,
										int MoveToX,
										int MoveToY,
										int MoveFromX,
										int MoveFromY
										)
{

	MATCharAnimation::Instance().SetAnimation(MATCharAnimation::ANIMATION_LAUGH);
	MATLevelManager::Instance().AddMatched(List);

	m_MatchCount++;
	int ScoreGot = CalculateScore((int)List.size());
	

	m_CurrentCombo++;
	
	//std::set<int>::iterator It;
	MATGem* BC;
	const int BOMSCORE = 45;
	for(int i = 0; i < (int)List.size(); i++)
	{
		
		BC = List[i];
		//It = m_PreviousMatchedGems.find(BC->m_Type);
		//if(It != m_PreviousMatchedGems.end())
		//{
			//m_SameColorCombo++;
		//	i = (int)List.size();
		//}


		if( YList[i] == MoveToY &&  XList[i] == MoveToX)
		{
			if(BC->m_IsBomb )
				ScoreGot += BOMSCORE;

			m_Score.Add(ScoreGot);
			
		}
		else if(BC->m_IsBomb )
		{
			
			MATSFXManager::Instance().AddFlySfxNumber(BOMSCORE,MATGame::GetBoardPos(YList[i],XList[i]) );
			m_Score.Add(BOMSCORE);
		}

	}

	int FlyTextPosX = MoveToX;
	int FlyTextPosY = MoveToY;

	if(MATLogicBoard::Instance().IsMatchedXY(MoveToY,MoveToX))
	{}
	else if(MATLogicBoard::Instance().IsMatchedXY(MoveFromY,MoveFromX))
	{
		FlyTextPosX = MoveFromX;
		FlyTextPosY = MoveFromY;
	}
	else
	{		
		FlyTextPosX = XList[(int)XList.size()-1];
		FlyTextPosY = XList[(int)YList.size()-1];
	}
	MATSFXManager::Instance().AddFlySfxNumber(	ScoreGot,
												MATGame::GetBoardPos(FlyTextPosY,FlyTextPosX)
												);

	m_PreviousMatchedGems.clear();
	for(int i = 0; i < (int)List.size(); i++)
		m_PreviousMatchedGems.insert(List[i]->m_Type);


	//if(m_SameColorCombo >= 2)
	//	m_UIComboSameColor.Show(m_SameColorCombo,10 , 0.1f);
	//else 
	if(m_CurrentCombo >= 2)
		m_UICombo.Show(m_CurrentCombo , 0.01f, 1.25f);

	m_Score.Add(CalculateBonus(m_CurrentCombo,false));

	
	MATUIAchievementGain* pPopup = NULL;
	std::vector<RMS_TYPE> RmsType;

	/*
	if(m_SameColorCombo == 2)
		RmsType.push_back(RMS_ACH_COLORCOMBO2);

	if(m_SameColorCombo == 3)
		RmsType.push_back(RMS_ACH_COLORCOMBO3);		
	*/

	//else 
		if(m_CurrentCombo == 3)
		RmsType.push_back(RMS_ACH_COMBO3);		

	else if(m_CurrentCombo == 4)
		RmsType.push_back(RMS_ACH_COMBO4);	

	else if(m_CurrentCombo == 5)
		RmsType.push_back(RMS_ACH_COMBO5);

	if(List.size() >= 13)
		RmsType.push_back(RMS_ACH_GEMS13);
	
	else if(List.size() >= 12)
		RmsType.push_back(RMS_ACH_GEMS12);

	else if(List.size() >= 11)
		RmsType.push_back(RMS_ACH_GEMS11);
	
	else if(List.size() >= 10)
		RmsType.push_back(RMS_ACH_GEMS10);
	
	else if(List.size() >= 9)
		RmsType.push_back(RMS_ACH_GEMS9);
	
	else if(List.size() >= 8)
		RmsType.push_back(RMS_ACH_GEMS8);
	
	else if(List.size() >= 7)
		RmsType.push_back(RMS_ACH_GEMS7);	


	if(g_pApp->GetRMS()->GetInt(RMS_ACH_ENTIREROW) == 0)
	{
		for(int y = 0; y < MATGameRule::Instance().GetBoardCountY(); y++)
		{
			for(int x = 0; x < MATGameRule::Instance().GetBoardCountX(); x++)
			{
				if( std::find(XList.begin(), XList.end(), x ) == XList.end() )
					break;
				else if( x == MATGameRule::Instance().GetBoardCountX() - 1)
					RmsType.push_back(RMS_ACH_ENTIREROW);				
				
			}
		}
	}

	if(g_pApp->GetRMS()->GetInt(RMS_ACH_ENTIRECOL) == 0)
	{
		for(int x = 0; x < MATGameRule::Instance().GetBoardCountX(); x++)
		{
			for(int y = 0; y < MATGameRule::Instance().GetBoardCountY(); y++)
			{
				if( std::find(YList.begin(), YList.end(), y ) == YList.end() )
					break;
				else if( y == MATGameRule::Instance().GetBoardCountY() - 1)
					RmsType.push_back(RMS_ACH_ENTIRECOL);
				
							
			}
		}
	}

	if(g_pApp->GetRMS()->GetInt(RMS_ACH_MAINDIAGONAL) == 0)
	{
		for(int x = 0, y = 0; x < MATGameRule::Instance().GetBoardCountX() && y < MATGameRule::Instance().GetBoardCountY(); x++, y++)
		{
			if( std::find(XList.begin(), XList.end(), x ) == XList.end() )
				break;
			else if( std::find(YList.begin(), YList.end(), y ) == YList.end() )
				break;
			else if( y == MATGameRule::Instance().GetBoardCountY() - 1 && x == MATGameRule::Instance().GetBoardCountX() - 1)
				RmsType.push_back(RMS_ACH_MAINDIAGONAL);				
				
		}
	}

	if(g_pApp->GetRMS()->GetInt(RMS_ACH_MAINDIAGONAL) == 0)
	{
		for(int x = 0, y = MATGameRule::Instance().GetBoardCountY() - 1; x < MATGameRule::Instance().GetBoardCountX() && y >= 0; x++, y--)
		{
			if( std::find(XList.begin(), XList.end(), x ) == XList.end() )
				break;
			else if( std::find(YList.begin(), YList.end(), y ) == YList.end() )
				break;
			else if( y == 0 && x == MATGameRule::Instance().GetBoardCountX() - 1)
				RmsType.push_back(RMS_ACH_MAINDIAGONAL);				
		}
	}
	
	if((int)RmsType.size() > 0)
	{
		//MATUIAchievementGain* pPoup = (MATUIAchievementGain*)MATUIPopupAnimatorMgr::Instance().GetPopup(MATUIPopupAnimatorMgr::POPUP_NAMES_ACHIEVEMENTGAIN);
		//if(pPopup)
		//{
		//	for(int i = 0; i < (int)RmsType.size(); i++)
		//		pPopup->GainAchievement(RmsType[i]);
		//}
	}
	

	
}

void		MATScoring::ClearGem(int Y, int X)
{
	const int SCORE = 35;
	MATSFXManager::Instance().AddFlySfxNumber(SCORE ,MATGame::GetBoardPos(Y,X) );
	m_Score.Add(SCORE);
}

void		MATScoring::ResetFromCombo()
{
	m_SameColorCombo = 1;
	m_CurrentCombo = 0;
	m_PreviousMatchedGems.clear();

}

void		MATScoring::NewGame()
{
	m_NextPeerScoreReportDelay = 4.0f;
	ResetFromCombo();
	m_Score.InitValue(0);
	m_MatchCount = 0;
	if(m_pUIProgressScore)
		m_pUIProgressScore->SetProgress(0);

	char Buffer[256];		
	
	for(int i = 0; i < 3; i++)
	{
		m_IsStarGot[i] = false;
		sprintf(Buffer, "star_small_%i", i+1);
		m_pUIStars[i]->SetOffImage(Buffer);
		

	}
}


void		MATScoring::Tick(float dt)
{
	//if(m_ShowCounter > 0)
	//	m_ShowCounter -= dt;
	m_UICombo.Tick(dt);
	//m_UIComboSameColor.Tick(dt);

	if(m_NextPeerScoreReportDelay > 0)
	{
		m_NextPeerScoreReportDelay -= dt;
		if(m_NextPeerScoreReportDelay <= 0)
		{
			m_NextPeerScoreReportDelay = 4.0f;
			NextPeerManager::Instance().ReportScore( m_Score.GetValue() );			
		}
	}

	m_Score.Tick(dt);
	if(m_pUIProgressScore)
	{
		const float TEMPVAL = (float)m_Score.GetShowValue() /(float) MATLevelManager::Instance().GetStarScore(2);
		if(TEMPVAL > 0)
			m_pUIProgressScore->SetProgress( TEMPVAL );
		
		for(int i = 0; i < 3; i++)
		{
			if( m_IsStarGot[i] == false)
			{
				if( m_Score.GetShowValue()  >= MATLevelManager::Instance().GetStarScore(i))
				{
					char Buffer[256];		
					m_IsStarGot[i] = true;
					MATSFXManager::Instance().Spawn(MATSfx::SFX_MATCH, m_pUIStars[i]->GetPosition()  ,1.0f,0,false,MATSounds::SFX_MATCH);
					sprintf(Buffer, "star_small_glow%i", i+1);
					m_pUIStars[i]->SetOffImage(Buffer);
					if(m_pUIStars[i])
						MATUIAnimator::Instance().Add(	m_pUIStars[i],
											MATAnimatedUI::ANIMATE_STYLE_STAMP,
											0 ,NULL);	
				}
				break;
			}
		}
	}
	
}

void		MATScoring::Render(float Scale)
{
	//m_UIComboSameColor.Render();
	m_UICombo.Render();

	
	m_Score.Render(Scale);	
	
}

int			MATScoring::CalculateScore(int Count)
{
	switch(Count-4)
	{
	case 1: return 50 + 25; 
	case 2: return 50 + 25 + 25;
	case 3: return 50 + 25 + 50 + 25;
	case 4: return 50 + 25 + 75 + 25;
	case 5: return 50 + 25 + 125 + 25;
	case 6: return 50 + 25 + 125 + 150 + 25;
	case 7: return 50 + 25 + 125 + 200 + 25;
	case 8: return 50 + 25 + 125 + 250 + 25;
	case 9: return 50 + 25 + 125 + 300 + 25;
	case 10: return 50 + 25 + 125 + 350 + 25;
	case 11: return 50 + 25 + 125 + 400 + 25;
	case 12: return 50 + 25 + 125 + 450 + 25;
	case 13: return 50 + 25 + 125 + 500 + 25;
	case 14: return 50 + 25 + 125 + 500 + 25;
	case 15: return 50 + 25 + 125 + 600 + 25;	
	}

	return 50 + 25 + 125 + 700;
}

int			MATScoring::CalculateBonus(int Combo, bool SameColor)
{
	int Val = Combo;
	if (SameColor)
		Val += 1;
	switch(Combo)
	{
	case 1: return 0;
	case 2: return 35;
	case 3: return 60; 
	case 4: return 100;	
	}
	return 150;
}